#!/usr/bin/env python3
"""
检查项目中缺失的包
根据代码中的import语句分析需要安装的第三方包
"""
import subprocess
import sys
import re
from pathlib import Path

def get_installed_packages():
    """获取已安装的包列表"""
    try:
        result = subprocess.run([sys.executable, "-m", "pip", "list"], 
                              capture_output=True, text=True)
        installed = set()
        for line in result.stdout.split('\n')[2:]:  # 跳过标题行
            if line.strip():
                package_name = line.split()[0].lower()
                installed.add(package_name)
        return installed
    except Exception as e:
        print(f"获取已安装包列表失败: {e}")
        return set()

def extract_imports_from_file(file_path):
    """从Python文件中提取import语句"""
    imports = set()
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
            
        # 匹配 import xxx 和 from xxx import yyy
        import_patterns = [
            r'^import\s+([a-zA-Z_][a-zA-Z0-9_]*)',
            r'^from\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+import'
        ]
        
        for line in content.split('\n'):
            line = line.strip()
            for pattern in import_patterns:
                match = re.match(pattern, line)
                if match:
                    module_name = match.group(1)
                    # 跳过相对导入和标准库
                    if not module_name.startswith('.') and module_name not in STANDARD_LIBRARY:
                        imports.add(module_name)
    except Exception as e:
        print(f"读取文件 {file_path} 失败: {e}")
    
    return imports

# Python标准库模块（部分）
STANDARD_LIBRARY = {
    'os', 'sys', 'json', 'time', 'datetime', 'pathlib', 'typing', 'uuid',
    'hashlib', 'pickle', 're', 'subprocess', 'argparse', 'asyncio',
    'concurrent', 'contextlib', 'dataclasses', 'enum', 'statistics',
    'collections', 'itertools', 'functools', 'operator', 'copy',
    'math', 'random', 'string', 'io', 'tempfile', 'shutil', 'glob'
}

# 包名映射（import名 -> pip包名）
PACKAGE_MAPPING = {
    'cv2': 'opencv-python',
    'PIL': 'Pillow',
    'yaml': 'PyYAML',
    'sklearn': 'scikit-learn',
    'bs4': 'beautifulsoup4',
    'docx': 'python-docx',
    'dotenv': 'python-dotenv',
    'multipart': 'python-multipart',
    'redis': 'redis',
    'psycopg2': 'psycopg2-binary',
    'sentence_transformers': 'sentence-transformers',
    'langchain_core': 'langchain-core',
    'langchain_community': 'langchain-community',
    'langchain_text_splitters': 'langchain-text-splitters',
    'pymilvus': 'pymilvus',
    'faiss': 'faiss-cpu',
    'transformers': 'transformers',
    'torch': 'torch',
    'torchvision': 'torchvision',
    'torchaudio': 'torchaudio',
    'accelerate': 'accelerate',
    'safetensors': 'safetensors',
    'huggingface_hub': 'huggingface-hub',
    'pydantic_settings': 'pydantic-settings',
    'sqlalchemy': 'sqlalchemy',
    'alembic': 'alembic',
    'fastapi': 'fastapi',
    'uvicorn': 'uvicorn',
    'starlette': 'starlette',
    'httpx': 'httpx',
    'requests': 'requests',
    'aiofiles': 'aiofiles',
    'loguru': 'loguru',
    'pytest': 'pytest',
    'matplotlib': 'matplotlib',
    'numpy': 'numpy',
    'pandas': 'pandas',
    'scipy': 'scipy',
    'nltk': 'nltk',
    'tqdm': 'tqdm',
    'regex': 'regex',
    'prometheus_client': 'prometheus-client',
    'hiredis': 'hiredis'
}

def main():
    """主函数"""
    print("🔍 检查项目中缺失的包...")
    
    # 获取已安装的包
    installed_packages = get_installed_packages()
    print(f"✓ 已安装包数量: {len(installed_packages)}")
    
    # 扫描项目文件
    project_imports = set()
    python_files = list(Path('.').rglob('*.py'))
    
    print(f"📁 扫描 {len(python_files)} 个Python文件...")
    
    for py_file in python_files:
        # 跳过虚拟环境和缓存目录
        if any(part in str(py_file) for part in ['.venv', '__pycache__', '.git', 'venv', 'env']):
            continue
            
        file_imports = extract_imports_from_file(py_file)
        project_imports.update(file_imports)
    
    print(f"📦 发现 {len(project_imports)} 个导入的包")
    
    # 检查缺失的包
    missing_packages = []
    
    for import_name in project_imports:
        # 获取对应的pip包名
        pip_package = PACKAGE_MAPPING.get(import_name, import_name)
        pip_package_lower = pip_package.lower().replace('-', '_').replace('_', '-')
        
        # 检查是否已安装
        if pip_package_lower not in installed_packages:
            missing_packages.append(pip_package)
    
    # 输出结果
    if missing_packages:
        print(f"\n❌ 发现 {len(missing_packages)} 个缺失的包:")
        print("-" * 50)
        for package in sorted(missing_packages):
            print(f"  - {package}")
        
        print(f"\n💡 安装命令:")
        print(f"pip install {' '.join(sorted(missing_packages))}")
        
        print(f"\n📝 或者安装完整依赖:")
        print(f"pip install -r requirements-gpu.txt")
        
    else:
        print("\n✅ 所有需要的包都已安装!")
    
    print(f"\n📋 项目使用的所有第三方包:")
    print("-" * 50)
    for import_name in sorted(project_imports):
        pip_package = PACKAGE_MAPPING.get(import_name, import_name)
        status = "✓" if pip_package.lower().replace('-', '_') in installed_packages else "❌"
        print(f"  {status} {import_name} -> {pip_package}")

if __name__ == "__main__":
    main()
